package com.lfy.modules.monitor;

import cn.hutool.extra.spring.SpringUtil;
import com.lfy.domain.anno.Describe;
import com.lfy.modules.common.config.thread.MyLinkedBlockingQueue;
import com.lfy.modules.monitor.domain.ThreadPoolMonitor;
import com.lfy.modules.monitor.service.MonitorService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池监控
 *
 * @author <a href="https://www.lvfeiy.top">吕飞扬</a>
 * @date 2024/4/2 14:04
 */

@Slf4j
@Describe("线程池监控任务")
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class ThreadPoolMontitor implements Job {
    private volatile static int OPEN_ALARM = 0;

    private static final MonitorService MONITOR_SERVICE;
    private static final ThreadPoolExecutor MAIN_THREAD_POOL;
    static {
        MONITOR_SERVICE = SpringUtil.getBean(MonitorService.class);
        MAIN_THREAD_POOL = SpringUtil.getBean("mainThreadPool");
    }

    public static void setOpenAlarm(int flag) {
        if (flag > 1 || flag < 0) {
            return;
        }
        OPEN_ALARM = flag;
    }

    public static int getOpenAlarm() {
        return OPEN_ALARM;
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        ThreadPoolMonitor threadPoolMonitor = new ThreadPoolMonitor();
        MyLinkedBlockingQueue queue = (MyLinkedBlockingQueue) MAIN_THREAD_POOL.getQueue();
        threadPoolMonitor.setCorePoolSize(MAIN_THREAD_POOL.getCorePoolSize())
                .setMaxPoolSize(MAIN_THREAD_POOL.getMaximumPoolSize())
                .setPoolSize(MAIN_THREAD_POOL.getPoolSize())
                .setPoolActiveSize(MAIN_THREAD_POOL.getActiveCount())
                .setPoolLargestSize(MAIN_THREAD_POOL.getLargestPoolSize())
                .setPoolCompletedTask(MAIN_THREAD_POOL.getCompletedTaskCount())
                .setPoolLoad((double) MAIN_THREAD_POOL.getActiveCount() / (double) MAIN_THREAD_POOL.getMaximumPoolSize())
                .setPoolMaxLoad((double) MAIN_THREAD_POOL.getLargestPoolSize() / (double) MAIN_THREAD_POOL.getMaximumPoolSize())
                .setQueueItemSize(queue.size())
                .setQueueSurplusSize(queue.remainingCapacity())
                .setQueueType(queue.getClass().getName())
                .setQueueSize(queue.getCapacity());


        // 保存监控数据
        try {
            MONITOR_SERVICE.save(threadPoolMonitor);
            if (OPEN_ALARM == 1) {
                //TODO 给root用户发送告警邮件

                log.info("告警器running");
            }
        } catch (Exception e) {
            log.warn("记录线程池异常 in package com.lfy.monitor ThreadPoolMontitor", e);
        }


    }
}
